package scatter.wxminiapp.rest.security.mobile;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.util.WxMaConfigHolder;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import scatter.common.LoginUser;
import scatter.common.rest.security.LoginUserExtPutService;
import scatter.wxminiapp.pojo.login.WxMaLoginUser;
import scatter.wxminiapp.pojo.po.WxMaUser;
import scatter.wxminiapp.rest.basic.config.CustomWxMaServiceImpl;
import scatter.wxminiapp.rest.basic.config.WxMaProperties;
import scatter.wxminiapp.rest.security.WxMiniappUserDetailsServiceListener;
import scatter.wxminiapp.rest.service.IWxMaUserService;

import java.util.List;
import java.util.Optional;

/**
 * 微信小程序手机号登录
 * Created by yangwei
 * Created at 2022/3/22 16:59
 */
@Component
@Slf4j
public class WxMiniappMobileUserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private WxMaService wxMaService;
    @Autowired
    private WxMaProperties mpProperties;

    @Autowired
    private IWxMaUserService iWxMaUserService;

    @Autowired(required = false)
    private List<WxMiniappUserDetailsServiceListener> wxMaUserDetailsServiceListeners;


    @Autowired(required = false)
    private List<LoginUserExtPutService> loginUserExtPutServices;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 这里的username实际是code
        String code = username;
        // 在provider中已经switch
        String appId = WxMaConfigHolder.get();
        // 到这里可以获取用户信息了

        WxMaPhoneNumberInfo phoneNoInfo = null;
        try {
            phoneNoInfo = ((CustomWxMaServiceImpl) wxMaService).getPhoneNoInfo(code);

        } catch (WxErrorException e) {
            throw new UsernameNotFoundException("小程序接口调用凭证失败，请检查code是否正确",e);
        }

        WxMaProperties.MaConfig mpConfig = mpProperties.abtainConfigByAppCodeOrAppId(appId);

        WxMaUser  byOpenidAndAppCode = iWxMaUserService.getByMobileAndAppCode(phoneNoInfo.getPurePhoneNumber(), mpConfig.getAppCode());

        if (byOpenidAndAppCode == null) {
            byOpenidAndAppCode = iWxMaUserService.insert(phoneNoInfo, mpConfig);
        }
        // 针对具体业务回调
        WxMaUser byId = iWxMaUserService.getById(byOpenidAndAppCode.getId());

        // 处理到这说明没有业务处理登录信息，这里默认处理
        WxMaLoginUser wxMaLoginUser = new WxMaLoginUser();

        // 帐号信息
        wxMaLoginUser.setId(byId.getId());
        wxMaLoginUser.setUsername(byId.getOpenId());
        wxMaLoginUser.setIsEnabled(true);
        wxMaLoginUser.setIsLocked(false);
        wxMaLoginUser.setIsExpired(false);

        // 密码信息
        wxMaLoginUser.setPassword(null);
        wxMaLoginUser.setIsCredentialsExpired(false);

        // 总体信息
        wxMaLoginUser.setWxMaUser(byId);

        // 默认添加用户权限
        wxMaLoginUser.addAuthority("user");

        LoginUser loginUser = null;
        if (wxMaUserDetailsServiceListeners != null) {
            for (WxMiniappUserDetailsServiceListener wxMaUserDetailsServiceListener : wxMaUserDetailsServiceListeners) {
                loginUser = wxMaUserDetailsServiceListener.onUserInfoReady(phoneNoInfo,byId,appId,wxMaLoginUser);
            }
        }
        LoginUser actualReturn = Optional.ofNullable(loginUser).orElse(wxMaLoginUser);

        // 扩展信息调用
        if (loginUserExtPutServices != null) {
            for (LoginUserExtPutService loginUserExtPutService : loginUserExtPutServices) {
                loginUserExtPutService.addExt(actualReturn);
            }
        }
        return actualReturn;
    }
}
